
/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2020原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.io.support.PropertySourceFactory;

/**
 * Annotation providing a convenient and declarative mechanism for adding a
 * {@link org.springframework.core.env.PropertySource PropertySource} to Spring's
 * {@link org.springframework.core.env.Environment Environment}. To be used in
 * conjunction with @{@link Configuration} classes.
 *
 * <h3>Example usage</h3>
 *
 * <p>Given a file {@code app.properties} containing the key/value pair
 * {@code testbean.name=myTestBean}, the following {@code @Configuration} class
 * uses {@code @PropertySource} to contribute {@code app.properties} to the
 * {@code Environment}'s set of {@code PropertySources}.
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;PropertySource("classpath:/com/myco/app.properties")
 * public class AppConfig {
 *
 *     &#064;Autowired
 *     Environment env;
 *
 *     &#064;Bean
 *     public TestBean testBean() {
 *         TestBean testBean = new TestBean();
 *         testBean.setName(env.getProperty("testbean.name"));
 *         return testBean;
 *     }
 * }</pre>
 *
 * <p>Notice that the {@code Environment} object is
 * {@link org.springframework.beans.factory.annotation.Autowired @Autowired} into the
 * configuration class and then used when populating the {@code TestBean} object. Given
 * the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
 *
 * <h3>Resolving <code>${...}</code> placeholders in {@code <bean>} and {@code @Value} annotations</h3>
 *
 * <p>In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
 * annotations using properties from a {@code PropertySource}, you must ensure that an
 * appropriate <em>embedded value resolver</em> is registered in the {@code BeanFactory}
 * used by the {@code ApplicationContext}. This happens automatically when using
 * {@code <context:property-placeholder>} in XML. When using {@code @Configuration} classes
 * this can be achieved by explicitly registering a {@code PropertySourcesPlaceholderConfigurer}
 * via a {@code static} {@code @Bean} method. Note, however, that explicit registration
 * of a {@code PropertySourcesPlaceholderConfigurer} via a {@code static} {@code @Bean}
 * method is typically only required if you need to customize configuration such as the
 * placeholder syntax, etc. See the "Working with externalized values" section of
 * {@link Configuration @Configuration}'s javadocs and "a note on
 * BeanFactoryPostProcessor-returning {@code @Bean} methods" of {@link Bean @Bean}'s
 * javadocs for details and examples.
 *
 * <h3>Resolving ${...} placeholders within {@code @PropertySource} resource locations</h3>
 *
 * <p>Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
 * resource location} will be resolved against the set of property sources already
 * registered against the environment. For example:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
 * public class AppConfig {
 *
 *     &#064;Autowired
 *     Environment env;
 *
 *     &#064;Bean
 *     public TestBean testBean() {
 *         TestBean testBean = new TestBean();
 *         testBean.setName(env.getProperty("testbean.name"));
 *         return testBean;
 *     }
 * }</pre>
 *
 * <p>Assuming that "my.placeholder" is present in one of the property sources already
 * registered &mdash; for example, system properties or environment variables &mdash;
 * the placeholder will be resolved to the corresponding value. If not, then "default/path"
 * will be used as a default. Expressing a default value (delimited by colon ":") is
 * optional. If no default is specified and a property cannot be resolved, an {@code
 * IllegalArgumentException} will be thrown.
 *
 * <h3>A note on property overriding with {@code @PropertySource}</h3>
 *
 * <p>In cases where a given property key exists in more than one {@code .properties}
 * file, the last {@code @PropertySource} annotation processed will 'win' and override
 * any previous key with the same name.
 *
 * <p>For example, given two properties files {@code a.properties} and
 * {@code b.properties}, consider the following two configuration classes
 * that reference them with {@code @PropertySource} annotations:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;PropertySource("classpath:/com/myco/a.properties")
 * public class ConfigA { }
 *
 * &#064;Configuration
 * &#064;PropertySource("classpath:/com/myco/b.properties")
 * public class ConfigB { }
 * </pre>
 *
 * <p>The override ordering depends on the order in which these classes are registered
 * with the application context.
 *
 * <pre class="code">
 * AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
 * ctx.register(ConfigA.class);
 * ctx.register(ConfigB.class);
 * ctx.refresh();
 * </pre>
 *
 * <p>In the scenario above, the properties in {@code b.properties} will override any
 * duplicates that exist in {@code a.properties}, because {@code ConfigB} was registered
 * last.
 *
 * <p>In certain situations, it may not be possible or practical to tightly control
 * property source ordering when using {@code @PropertySource} annotations. For example,
 * if the {@code @Configuration} classes above were registered via component-scanning,
 * the ordering is difficult to predict. In such cases &mdash; and if overriding is important
 * &mdash; it is recommended that the user fall back to using the programmatic
 * {@code PropertySource} API. See {@link org.springframework.core.env.ConfigurableEnvironment
 * ConfigurableEnvironment} and {@link org.springframework.core.env.MutablePropertySources
 * MutablePropertySources} javadocs for details.
 *
 * <p><b>NOTE: This annotation is repeatable according to Java 8 conventions.</b>
 * However, all such {@code @PropertySource} annotations need to be declared at the same
 * level: either directly on the configuration class or as meta-annotations on the
 * same custom annotation. Mixing direct annotations and meta-annotations is not
 * recommended since direct annotations will effectively override meta-annotations.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Phillip Webb
 * @author Sam Brannen
 * @since 3.1
 * @see PropertySources
 * @see Configuration
 * @see org.springframework.core.env.PropertySource
 * @see org.springframework.core.env.ConfigurableEnvironment#getPropertySources()
 * @see org.springframework.core.env.MutablePropertySources
 */
/**
 *注释为添加
 *｛@link org.springframework.core.env.PropertySource PropertySource｝到Spring的
 *｛@link org.springframework.core.env.env.Environment环境｝。用于
 *与@｛@link配置｝类结合使用。
 *
 *<h3>示例用法</h3>
 *
 *<p>给定一个包含键/值对的文件{@code-app.properties}
 *｛@code testbean.name＝myTestBean｝，下面的｛@code@Configuration｝类
 *使用{@code@PropertySource}向
 *｛@code Environment｝的｛@codePropertySources｝集合。
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;PropertySource（“classpath:/com/myco/app.properties”）
 *公共类AppConfig{
 *
 *     &#064;自动装配
 *环境环境；
 *
 *     &#064;豆
 *公共TestBean TestBean（）{
 *TestBean TestBean=新的TestBean（）；
 *testBean.setName（env.getProperty（“testBean.name”））；
 *返回testBean；
 *     }
 *}</pre>
 *
 *＜p＞请注意，｛@code Environment｝对象是
 *｛@将org.springframework.beans.factory.annotation.Autowired@Autowired｝链接到
 *配置类，然后在填充{@code-TestBean}对象时使用。鉴于
 *在上面的配置中，对{@code-testBean.getName（）}的调用将返回“myTestBean”。
 *
 *＜h3＞解析｛@code＜bean＞｝和｛@code@Value｝注释中的＜code＞$｛…｝＜/code＞占位符</h3>
 *
 *＜p＞为了解析｛@code＜bean＞｝定义或｛@code@Value｝中的$｛…｝占位符
 *使用{@code PropertySource}中的财产的注释，必须确保
 *适当的<em>嵌入值解析器</em>在｛@code BeanFactory｝中注册
 *由｛@code ApplicationContext｝使用。使用时会自动发生这种情况
 *｛@code＜context:属性占位符＞｝。使用｛@code@Configuration｝类时
 *这可以通过显式注册｛@code PropertySourcesPlaceholderConfigurer｝来实现
 *通过{@code-static}{@code@Bean}方法。然而，请注意，明确的注册
 *通过｛@code static｝｛@code@Bean｝
 *方法通常仅在需要自定义配置（如
 *占位符语法等。请参阅
 *｛@link Configuration@Configuration｝的javadocs和“关于
 *BeanFactoryPostProcessor返回｛@link-Bean@Bean｝的｛@code@Bean}方法
 *有关详细信息和示例的javadocs。
 *
 *<h3>解析{@code@PropertySource}资源位置内的$｛…｝占位符</h3>
 *
 *<p>｛@code@PropertySource｝｛@linkplain#value（）中存在的任何$｛…｝占位符
 *资源位置｝将根据属性源集进行解析
 *针对环境注册。例如：
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;PropertySource（“classpath:/com/${my.placeholder:default/path}/app.properties”）
 *公共类AppConfig{
 *
 *     &#064;自动装配
 *环境环境；
 *
 *     &#064;豆
 *公共TestBean TestBean（）{
 *TestBean TestBean=新的TestBean（）；
 *testBean.setName（env.getProperty（“testBean.name”））；
 *返回testBean；
 *     }
 *}</pre>
 *
 *<p>假设其中一个属性源中已经存在“my.placeholder”
 *已注册&mdash；例如，系统财产或环境变量&mdash；
 *占位符将被解析为相应的值。如果没有，则为“默认/路径”
 *将用作默认值。表示默认值（由冒号“：”分隔）为
 *可选。如果未指定默认值并且无法解析属性，则｛@code
 *将引发IllegalArgumentException｝。
 *
 *＜h3＞关于用｛@code@PropertySource｝重写属性的说明</h3>
 *
 *<p>如果给定的属性键存在于多个{@code.财产中
 *文件，处理的最后一个｛@code@PropertySource｝注释将“获胜”并覆盖
 *任何以前具有相同名称的密钥。
 *
 *<p>例如，给定两个财产文件{@code a.properties}和
 *{@codeb.properties}，考虑以下两个配置类
 *使用｛@code@PropertySource｝注释引用它们：
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;PropertySource（“classpath:/com/myc/a.properties”）
 *公共类ConfigA｛｝
 *
 * &#064;配置
 * &#064;PropertySource（“classpath:/com/myc/b.properties”）
 *公共类ConfigB｛｝
 *</pre>
 *
 *<p>覆盖顺序取决于这些类的注册顺序
 *与应用程序上下文关联。
 *
 *<pre-class=“code”>
 *AnnotationConfigApplicationContext ctx=新的AnnotationConfigurationApplicationContext（）；
 *ctx.register（ConfigA.class）；
 *ctx.register（配置B.class）；
 *ctx.refresh（）；
 *</pre>
 *
 *<p>在上述场景中，{@codeb.properties}中的财产将覆盖任何
 *{@code a.properties}中存在重复项，因为{@code ConfigB}已注册
 *最后。
 *
 *<p>在某些情况下，严格控制可能是不可能的，也不实际
 *使用｛@code@PropertySource｝注释时的属性源排序。例如
 *如果上述{@code@Configuration}类是通过组件扫描注册的，
 *排序很难预测。在这种情况下；如果覆盖很重要
 *&mdash；建议用户重新使用程序
 *｛@code PropertySource｝API。请参阅｛@link org.springframework.core.env.ConfigurableEnvironment
 *可配置环境｝和｛@link org.springframework.core.env.MutablePropertySources
 *MutablePropertySources｝javadocs获取详细信息。
 *
 *<p><b>注意：根据Java 8惯例，此注释是可重复的</b>
 *然而，所有这样的{@code@PropertySource}注释都需要同时声明
 *级别：直接在配置类上，或者作为
 *相同的自定义注释。不能混合使用直接注释和元注释
 *建议使用，因为直接注释将有效地覆盖元注释。
 *
 *@作者Chris Beams
 *@作者Juergen Hoeller
 *@作者Phillip Webb
 *@作者Sam Brannen
 *@自3.1起
 *@请参阅PropertySources
 *@请参阅配置
 *@参见org.springframework.core.env.PropertySource
 *请参阅org.springframework.core.env.ConfiguratableEnvironment#getPropertySources（）
 *@参见org.springframework.core.env.MutablePropertySources
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {

	/**
	 * Indicate the name of this property source. If omitted, the {@link #factory}
	 * will generate a name based on the underlying resource (in the case of
	 * {@link org.springframework.core.io.support.DefaultPropertySourceFactory}:
	 * derived from the resource description through a corresponding name-less
	 * {@link org.springframework.core.io.support.ResourcePropertySource} constructor).
	 * @see org.springframework.core.env.PropertySource#getName()
	 * @see org.springframework.core.io.Resource#getDescription()
	 */
	/**
	 *指示此属性源的名称。如果省略，则｛@link#factory｝
	 *将基于基础资源生成一个名称（在
	 *｛@link org.springframework.core.io.support.DefaultPropertySourceFactory｝：
	 *通过相应的名称less从资源描述派生
	 *｛@link org.springframework.core.io.support.ResourcePropertySource｝构造函数）。
	 *请参阅org.springframework.core.env.PropertySource#getName（）
	 *请参阅org.springframework.core.io.Resource#getDescription（）
	 */
	String name() default "";

	/**
	 * Indicate the resource location(s) of the properties file to be loaded.
	 * <p>Both traditional and XML-based properties file formats are supported
	 * &mdash; for example, {@code "classpath:/com/myco/app.properties"}
	 * or {@code "file:/path/to/file.xml"}.
	 * <p>Resource location wildcards (e.g. *&#42;/*.properties) are not permitted;
	 * each location must evaluate to exactly one {@code .properties} or {@code .xml}
	 * resource.
	 * <p>${...} placeholders will be resolved against any/all property sources already
	 * registered with the {@code Environment}. See {@linkplain PropertySource above}
	 * for examples.
	 * <p>Each location will be added to the enclosing {@code Environment} as its own
	 * property source, and in the order declared.
	 */
	/**
	 *指示要加载的财产文件的资源位置。
	 *<p>支持传统和基于XML的财产文件格式
	 *&mdash；例如，{@code“classpath:/com/myc/app.properties”}
	 *或{@code“file:/path/to/file.xml”}。
	 *<p>不允许使用资源位置通配符（例如*&#42；/*.财产）；
	 *每个位置的计算结果必须恰好为一个{@code.财产}或{@code.xml}
	 *资源。
	 *<p>$｛…｝占位符将针对任何/所有属性源进行解析
	 *已在｛@code Environment｝中注册。请参阅上面的｛@linkplain PropertySource｝
	 *例如。
	 *＜p＞每个位置都将作为自己的位置添加到封闭的｛@code Environment｝中
	 *属性源，并按声明的顺序。
	 */
	String[] value();

	/**
	 * Indicate if a failure to find a {@link #value property resource} should be
	 * ignored.
	 * <p>{@code true} is appropriate if the properties file is completely optional.
	 * <p>Default is {@code false}.
	 * @since 4.0
	 */
	/**
	 *指示查找｛@link#value属性资源｝失败是否应为
	 *已忽略。
	 *如果财产文件是完全可选的，那么<p>{@code-true}是合适的。
	 *＜p＞默认值为｛@code false｝。
	 *@自4.0起
	 */
	boolean ignoreResourceNotFound() default false;

	/**
	 * A specific character encoding for the given resources, e.g. "UTF-8".
	 * @since 4.3
	 */
	/**
	 *给定资源的特定字符编码，例如“UTF-8”。
	 *@自4.3起
	 */
	String encoding() default "";

	/**
	 * Specify a custom {@link PropertySourceFactory}, if any.
	 * <p>By default, a default factory for standard resource files will be used.
	 * @since 4.3
	 * @see org.springframework.core.io.support.DefaultPropertySourceFactory
	 * @see org.springframework.core.io.support.ResourcePropertySource
	 */
	/**
	 *指定自定义｛@link PropertySourceFactory｝（如果有）。
	 *<p>默认情况下，将使用标准资源文件的默认工厂。
	 *@自4.3起
	 *@请参阅org.springframework.core.io.support.DefaultPropertySourceFactory
	 *@请参阅org.springframework.core.io.support.ResourcePropertySource
	 */
	Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;

}
